﻿
namespace Contour.Contrib.FieldTypes
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    using Umbraco.Forms.Core;
    using Umbraco.Forms.Core.Attributes;

    using umbraco;
    using umbraco.presentation.nodeFactory;

    /// <summary>
    /// The Label field type
    /// </summary>
    public class Label : FieldType
    {
        #region Constructors and Destructors

        public Label()
        {
            this.Id = new Guid("57ADD3AB-C3CD-464D-BCC2-3D1C05D3BF67");
            this.Name = "Label";
            this.Description = "A read-only field used to display blocks of text";
            this.Icon = "label.png"; // needs to be in the \umbraco\plugins\umbracoContour\images\fieldtypes directory
            this.DataType = FieldDataType.String;
            this.Value = new List<object>();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets value.
        /// </summary>
        public List<object> Value;

        /// <summary>
        /// Gets or sets TextToShow
        /// </summary>
        [Setting("Text To Show", prevalues = "",
           description = "Enter the text to show in the label.  You can also use [#fieldName] to pull the value from the current page.",
           control = "Umbraco.Forms.Core.FieldSetting.TextArea")]
        public string TextToShow { get; set; }

        /// <summary>
        /// Gets or sets HideFieldCaption
        /// </summary>
        [Setting("Hide Field Caption", prevalues = "",
            description = "Select to hide the field name/label and only show the text",
            control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
        public string HideFieldCaption { get; set; }

        /// <summary>
        /// Gets or sets Editor
        /// </summary>
        public override System.Web.UI.WebControls.WebControl Editor
        {
            get
            {
                System.Web.UI.WebControls.Panel pnl = new System.Web.UI.WebControls.Panel();
                pnl.ID = "pnlHolder";
                pnl.CssClass = "contourlabelfield";

                // Adds a CSS class if the "Hide Caption" option is enabled, so can be styled differently if desired
                if (HideFieldCaption == "checked")
                    pnl.CssClass += " nolabel";

                string actualText = ParseTokens(TextToShow);

                pnl.Controls.Add(new System.Web.UI.LiteralControl("<p>" + umbraco.library.ReplaceLineBreaks(actualText) + "</p>"));
                return pnl;
            }
            set
            {
                base.Editor = value;
            }
        }

        public override List<object> Values
        {
            get
            {
                Value.Clear();
                Value.Add(string.Empty);
                return Value;

            }
            set
            {
                Value = value;
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// The HideLabel option
        /// </summary>
        public override bool HideLabel
        {
            get
            {
                return HideFieldCaption == "checked";
            }
            set
            {
                base.HideLabel = value;
            }
        }

        /// <summary>
        /// The render preview.
        /// </summary>
        /// <returns>
        /// The preview.
        /// </returns>
        public override string RenderPreview()
        {
            return "<p>" + umbraco.library.ReplaceLineBreaks(TextToShow) + "</p>";
        }

        /// <summary>
        /// The render preview with prevalues.
        /// </summary>
        /// <param name="prevalues">
        /// The prevalues.
        /// </param>
        /// <returns>
        /// The preview with prevalues
        /// </returns>
        public override string RenderPreviewWithPrevalues(List<object> prevalues)
        {
            return this.RenderPreview();
        }

        public override bool SupportsRegex
        {
            get { return false; }
        }

        public override bool SupportsPrevalues
        {
            get { return false; }
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// Helper method to parse tokens (mimics Advanced Macro Parameter Syntax)
        /// </summary>
        /// <param name="text">The tokenized text to parse (eg. [#fieldName])</param>
        /// <returns>The parsed text</returns>
        public string ParseTokens(string text)
        {
            if (text.Length > 3 && text.StartsWith("["))
            {
                Node currentNode;
                // we need an empty try/catch as Node.GetCurrent() will throw an exception if we're outside of Umbraco Context
                try
                {
                    currentNode = Node.GetCurrent();
                }
                catch { currentNode = null; }

                string[] textSplit = text.Split(',');

                foreach (string item in textSplit)
                {

                    if (TextToShow.StartsWith("[") && TextToShow.EndsWith("]"))
                    {
                        string keyName = item.Substring(2, item.Length - 3);
                        string keyType = item.Substring(1, 1);

                        switch (keyType)
                        {
                            case "@":
                                text = HttpContext.Current.Request[keyName];
                                break;
                            case "%":
                                text = umbraco.BusinessLogic.StateHelper.GetSessionValue<string>(keyName);
                                break;
                            case "^":
                                text = library.GetDictionaryItem(keyName);
                                break;
                            case "#":
                                if (currentNode != null && currentNode.GetProperty(keyName) != null)
                                {
                                    text = currentNode.GetProperty(keyName).Value;
                                }
                                else
                                {
                                    text = "";
                                }
                                break;
                            case "$":
                                if (currentNode != null)
                                {
                                    text = GetPropertyValueRecursive(currentNode, keyName);
                                }
                                break;
                        }
                        if (text != null)
                        {
                            text = text.Trim();
                            if (text != string.Empty)
                                break;
                        }
                        else
                        {
                            text = string.Empty;
                        }
                    }

                }
            }
            return text;
        }

        /// <summary>
        /// Returns the value (not null and empty) of the property with the given alias recursively
        /// </summary>
        /// <param name="node">The node</param>
        /// <param name="propertyAlias">The alias of the property</param>
        /// <returns>The property's value</returns>
        public static string GetPropertyValueRecursive(Node node, string propertyAlias)
        {
            if (node.GetProperty(propertyAlias) != null && !string.IsNullOrEmpty(node.GetProperty(propertyAlias).Value))
                return node.GetProperty(propertyAlias).Value;

            if (node.Parent != null)
                return GetPropertyValueRecursive(new Node(node.Parent.Id), propertyAlias);

            return string.Empty;
        }
        #endregion
    }
}